package streamforce.crypto.cloud.subscriber;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import streamforce.Stat;
import streamforce.crypto.KPAbe;
import streamforce.crypto.cloud.EPCloud;
import streamforce.crypto.cloud.EPCloudServer;
import streamforce.crypto.cloud.TimeTuple;
import streamforce.crypto.cloud.Tuple;
import streamforce.crypto.event.Ciphertext;
import streamforce.crypto.event.StockEvent;
import streamforce.crypto.event.StockEventJoin;
import streamforce.crypto.event.TransformedCTEventJoin;
import streamforce.crypto.policies.Policy;

/**
 * Had the join result. Now transform the result 
 */
public class CloudJoinPriceStage2 extends Policy{
	private final Log log = LogFactory.getLog(CloudJoinPriceStage2.class);
	int userId1, userId2; //user ID for join
	Stat stat, statTuple;
	public CloudJoinPriceStage2(int userId1, int userId2, KPAbe ch){
		super(ch); 
		this.userId1 = userId1;
		this.userId2 = userId2;
		stat = new Stat("nJoins");
		statTuple = new Stat("nTuples"); 
	}
	//price here is encrypted with ws=1
	public  void update(int ts1, int hour1, int sid1, int ts2, int hour2, int sid2, Ciphertext price, Ciphertext volume1,
			Ciphertext volume2) {
		TimeTuple tt = EPCloudServer.tupleTime.get(new Tuple(sid1, ts1)); 
		/*if (tt.getCount()==0)
			this.statTuple.update();*/ 			
		tt.increaseCount(); 
		/*if (EPCloudServer.QUEUE_DUMP)
			log.info(String.format("queue (%d,%d): %d", sid1,
					ts1,
					(System.currentTimeMillis() - tt.getStart())));*/
		
		tt = EPCloudServer.tupleTime.get(new Tuple(sid2, ts2)); 
		/*if (tt.getCount()==0)
			this.statTuple.update(); */			
		tt.increaseCount();
		/*if (EPCloudServer.QUEUE_DUMP)
			log.info(String.format("queue (%d,%d): %d", sid2,
					ts2,
					(System.currentTimeMillis() - tt.getStart())));*/
		
		/*log.debug("("+sid1+","+ts1+"): queue = "
				+ (System.currentTimeMillis() - EPCloudServer.tupleTime
						.get(new Tuple(sid1, ts1)))+" uid = "+this.userId1);
		log.debug("("+sid2+","+ts2+"): queue = "
				+ (System.currentTimeMillis() - EPCloudServer.tupleTime
						.get(new Tuple(sid2, ts2)))+" uid = "+this.userId2);	*/	
		
		byte[][] originals, transforms; 
		//byte[] ciphertext = price.getCipher();
		long start = System.currentTimeMillis();
		/*byte[] oct = this.cryptoHandler.extractOriginalCipher(sid1, ciphertext);
		byte[] tct = this.cryptoHandler.transform_simple(ciphertext, sid1,this.userId1);
		this.stat.update();*/		
				
		//volume1
		byte[] oct = this.cryptoHandler.extractOriginalCipher(sid1, volume1.getCipher());
		byte[] tct = this.cryptoHandler.transform_simple(volume1.getCipher(), sid1, this.userId1);
		//this.stat.update();
		originals = new byte[2][oct.length];
		transforms = new byte[2][tct.length];
		originals[0] = oct; 
		transforms[0] = tct;				
		
		//volume2
		oct = this.cryptoHandler.extractOriginalCipher(sid2, volume2.getCipher());
		tct = this.cryptoHandler.transform_simple(volume2.getCipher(), sid2, this.userId2);
		this.stat.update();
		originals[1] = oct;
		transforms[1] = tct;

		long end = System.currentTimeMillis();
		log.info("join transform time = " + (end - start));
				
			// then construct and send another event
		TransformedCTEventJoin cte = new TransformedCTEventJoin(
				this.userId1, this.userId2, ts1, hour1, sid1, ts2, hour2, sid2, originals,
				transforms);		
		//EPCloud.getEPServiceProvider().getEPRuntime().sendEvent(cte);
	}		
}
